package info.cs52.bioinfo.hatien;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;


import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.assignment.ColorAction;
import prefuse.action.layout.graph.NodeLinkTreeLayout;
import prefuse.controls.PanControl;
import prefuse.controls.ZoomControl;
import prefuse.data.io.DataIOException;
import prefuse.render.DefaultRendererFactory;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;

import com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel;

public class Application extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6429651514701538997L;
	
	public Application() throws DataIOException {
		input = new InputReader().read("tree00.xml");
		initAlgorithm();
				
		initComponents();
		vis.run("color");  // assign the colors
		vis.run("layout"); // start up the animated layout
	}
	
	private void initComponents() {
		initVisualization();
		initRightPanel();
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.pack();           // layout components in window
	}
	
	private void initRightPanel() {
		nextBtn.setText("Tiếp theo");
		nextBtn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				algo.next();
			}
		});
		rightPnl.add(nextBtn);

		endBtn.setText("Cuối");
		endBtn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				algo.end();
			}
		});
		rightPnl.add(endBtn);
		
		rewindBtn.setText("Quay lại");
		rewindBtn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				algo.rewind();
			}
		});
		rightPnl.add(rewindBtn);

		rightPnl.add(new JLabel("Dùng trái chuột để di chuyển, phải chuột để thu phóng."));
		
		getContentPane().add(rightPnl, BorderLayout.NORTH);
	}
	
	private void initAlgorithm() {
		algo = new SankoffAlgorithm(input);
		algo.addAlgorithmListener(new AlgorithmListener() {
			
			@Override
			public void stepPerformed(Algorithm algo) {
				vis.repaint();
			}
		});
	}

	private void initVisualization() {
		vis = new Visualization();
		vis.add("tree", input.getTree());
		HatienNodeRenderer r = new HatienNodeRenderer(NUCLEOTID_COUNT);
		vis.setRendererFactory(new DefaultRendererFactory(r));
		// use light grey for edges
		ColorAction edges = new ColorAction("tree.edges",
				VisualItem.STROKECOLOR, ColorLib.gray(200));

		// create an action list containing all color assignments
		ActionList color = new ActionList();
		color.add(edges);
		// create an action list with an animated layout
		// the INFINITY parameter tells the action list to run indefinitely
		ActionList layout = new ActionList();
		layout.add(new NodeLinkTreeLayout("tree", Constants.ORIENT_TOP_BOTTOM, 15.0, 15.0, 15.0));
		// add the actions to the visualization
		vis.putAction("color", color);
		vis.putAction("layout", layout);
		// create a new Display that pull from our Visualization
		Display display = new Display(vis);
		display.setSize(720, 500); // set display size
		//display.addControlListener(new DragControl()); // drag items around
		display.addControlListener(new PanControl());  // pan with background left-drag
		display.addControlListener(new ZoomControl()); // zoom with vertical right-drag
		getContentPane().add(display, BorderLayout.CENTER);
	}
	
	public static void main(String[] args) throws InterruptedException, InvocationTargetException {		

		
		SwingUtilities.invokeAndWait(new Runnable() {
			
			@Override
			public void run() {
				try {
					UIManager.setLookAndFeel(NimbusLookAndFeel.class.getName());
					new Application().setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		

	}

	private static final int NUCLEOTID_COUNT = 4;
	private JPanel rightPnl = new JPanel();
	private JButton nextBtn = new JButton();
	private JButton endBtn = new JButton();
	private JButton rewindBtn = new JButton();
	private Visualization vis;
	private Algorithm algo;
	private Input input;

}
